<?php

require_once 'stream.php';
require_once 'tree.php';

class Parser
{
    public $tree = null;
    private $stack_to_tree = array ();
    protected $stream = null;
    private $position = 0;
    protected $main = null;

    function __construct()
    {
        $this->stream =& new Stream();
        $this->tree =& new Tree();
    }


    public function Process($text)
    {
        $this->stream->setStream($text);
        if (empty($this->main)) {
            return false;
        }
        $this->{$this->main}();

        return $this->tree->getDOM();
    }

    function Ch()
    {
        while (in_array($this->stream->getCharRef($this->position), array (0xA, 0xD, 0x20, 0x9))) {
            $this->position++;
        }
        return $this->stream->getCharRef($this->position);
    }

    function NextCh()
    {
        array_push($this->stack_to_tree, $this->Ch());
        $this->position++;
    }

    function createChild($name)
    {
        $this->_flushStackToTree();
        $this->tree->createChild($name);
    }

    function endChild()
    {
        $this->_flushStackToTree();
        $this->tree->endChild();
    }

    function toTree($chr)
    {
        array_push($this->stack_to_tree, $chr);
    }

    function Error($text='')
    {
        echo 'ERROR on column '.($this->position + 1).': '.$text;
        die();
    }

    private function _flushStackToTree()
    {
        if (count($this->stack_to_tree)) {
            $text = '';
            foreach ($this->stack_to_tree as $chr) {
                $text .= $chr;
            }
            $this->tree->write($text);
            $this->stack_to_tree = array ();
        }
    }


}

?>